

function [mov,imscaled] = generateGuNoise_xyt_v2_0(params,framerate,degperpix)


binarize=1;
contrast_luminance=1;%0.8;
% screen-specific parameters
screenWidthPix = 1280;        %% Screen width in Pixels
screenWidthCm =37.5;         %% Width in cm


if nargin <1 || isempty(params)
    duration = 1/30; % in minutes; this is andermann default
    maxSpatFreq = 0.32;         %% spatial frequency cutoff (cpd)
    maxTempFreq = 4;          %% temporal frequency cutoff
    imsize = 136;                %% size in pixels
    imageMag=4;                 %% magnification that movie will be played at
    screenDistanceCm = 22;      %% Distance in cm
else
    if isfield(params,'duration')
        duration = params.duration;
    elseif isfield(params,'totalStimLength')
        duration = params.totalStimLength/60;
    end
    maxSpatFreq = params.maxSpatFreq;
    maxTempFreq = params.maxTempFreq;
    imsize = params.imsize;
    imageMag = params.imageMag;
    screenDistanceCm = params.screenDistanceCm;
end
   
if nargin < 2 || isempty(framerate)
    framerate = 60;             % Hz
end


%% derived parameters for screen/movie
nframes = framerate*60*duration;
screenWidthDeg = 2*atan(0.5*screenWidthCm/screenDistanceCm)*180/pi;


if nargin < 3 || isempty(degperpix)
    degperpix = (screenWidthDeg/screenWidthPix)*imageMag;
end
contrastSigma =0.5;         %% one-sigma value for contrast


%% frequency intervals for FFT
nyq_pix = 0.5;
nyq_deg=nyq_pix/degperpix;
freqInt_deg = nyq_deg / (0.5*imsize);
freqInt_pix = nyq_pix / (0.5*imsize);

nyq = framerate/2;
tempFreq_int = nyq/(0.5*nframes);

%% cutoffs in terms of frequency intervals
tempCutoff = round(maxTempFreq/tempFreq_int);
maxFreq_pix = maxSpatFreq*degperpix;
spatCutoff = round(maxFreq_pix / freqInt_pix);
offsetFreq=0.05;
offset=round(offsetFreq*degperpix/freqInt_pix);

alpha=-1;
range_mult =1;

%% generate a Gaussian - can clean this up since it's weirdly written...

spaceRange = (imsize/2 - range_mult*spatCutoff : imsize/2 + range_mult*spatCutoff)+1;
tempRange =   (nframes /2 - range_mult*tempCutoff : nframes/2 + range_mult*tempCutoff)+1;
[x, y, z] = meshgrid(-range_mult*spatCutoff:range_mult*spatCutoff,-range_mult*spatCutoff:range_mult*spatCutoff,-range_mult*tempCutoff:range_mult*tempCutoff);

use =single(((x.^2 + y.^2)<=(spatCutoff^2))& ((z.^2)<(tempCutoff^2)) ).*((sqrt(x.^2 + y.^2) +offset).^alpha);
clear x y z;

%% use the Gaussian as a mask for random noise generated in Fourier space with the particular space/time constraints
invFFT = zeros(imsize,imsize,nframes,'single');
mu = zeros(size(spaceRange,2), size(spaceRange,2), size(tempRange,2));
sig = ones(size(spaceRange,2), size(spaceRange,2), size(tempRange,2));
invFFT(spaceRange, spaceRange, tempRange) = single(use .* normrnd(mu,sig).*exp(2*pi*1i*rand(size(spaceRange,2), size(spaceRange,2), size(tempRange,2))));
clear use;

fullspace = -range_mult*spatCutoff:range_mult*spatCutoff; halftemp = 1:range_mult*tempCutoff;
halfspace = 1:range_mult*spatCutoff;
invFFT(imsize/2 + fullspace+1, imsize/2+fullspace+1, nframes/2 + halftemp+1) = ...
    conj(invFFT(imsize/2 - fullspace+1, imsize/2-fullspace+1, nframes/2 - halftemp+1));
invFFT(imsize/2+fullspace+1, imsize/2 + halfspace+1,nframes/2+1) = ...
    conj( invFFT(imsize/2-fullspace+1, imsize/2 - halfspace+1,nframes/2+1));
invFFT(imsize/2+halfspace+1, imsize/2 +1,nframes/2+1) = ...
    conj( invFFT(imsize/2-halfspace+1, imsize/2+1,nframes/2+1));

shiftinvFFT = ifftshift(invFFT);
clear invFFT;

%% take inverse fourier transform to make real movie:

imraw = real(ifftn(shiftinvFFT));
immean = mean(imraw(:));
immax = std(imraw(:))/contrastSigma;
immin = -1*immax;
imscaled = (imraw - immin-immean) / (immax - immin);

if binarize
    imscaled(imscaled<0.5)=1-contrast_luminance;
    imscaled(imscaled>0.5)=1*contrast_luminance;
end


    
mov = uint8(floor(imscaled(1:imsize,1:imsize,:)*255)+1);


